#include "offset_classifier.h"
#include "libsvm_classifier.h"

#include <fstream>
#include <iostream>

static string get_name(string filename) {
	return filename + ".offset.txt";
}

bool offset_classifier::train(boosting_problem & prob, double * d_t, int argc, char ** argv) {
	base = get_base_classifier();
	bool result = base->train(prob, d_t, argc, argv);

	if(result) {
		threshold = 0.5;
		for(int i = 0; i < prob.l; i++) {
			if(prob.y[i] == 1) {
				double r = base->test(prob.x[i]);
				if(r < threshold) {
					threshold = r;
				}
			}
		}
	}

	return result;
}

double offset_classifier::test(boosting_node * x) {
	double r = base->test(x);
	double s;
	if(r >= threshold) {
		s = 0.5 * (r - threshold) / (1 - threshold) + 0.5;
	} else {
		s = 0.5 * r / threshold;
	}
	return s;
}

void offset_classifier::load(string filename){
	base = get_base_classifier();
	base->load(filename);

	string fn = get_name(filename);
	ifstream fin(fn.c_str());
	if(fin.fail()) {
		cout << "cannot find " << fn << endl;
	}
	fin >> threshold;
	fin.close();
}

void offset_classifier::dump(string filename) {
	base->dump(filename);

	string fn = get_name(filename);
	ofstream fout(fn.c_str());
	fout << threshold << endl;
	fout.close();
}

offset_classifier::offset_classifier() {
	base = NULL;
}

offset_classifier::~offset_classifier() {
	if(base != NULL) {
		delete base;
	}
}

base_classifier * offset_libsvm_classifier::get_base_classifier() {
	return new libsvm_classifier();
}
